package com.ssy.lingxi.system.service.impl;

import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.api.feign.paas.LanguagePAASControllerFeign;
import com.ssy.lingxi.platform.manage.api.model.dto.language.LanguagePAASDTO;
import com.ssy.lingxi.system.dao.LanguageRepository;
import com.ssy.lingxi.system.dao.SiteRepository;
import com.ssy.lingxi.system.dto.request.LanguageDeleteRequest;
import com.ssy.lingxi.system.dto.request.LanguageListRequest;
import com.ssy.lingxi.system.dto.response.LanguageListResponse;
import com.ssy.lingxi.system.dto.response.MiddlegroundUserLoginResponse;
import com.ssy.lingxi.system.entity.Language;
import com.ssy.lingxi.system.entity.Site;
import com.ssy.lingxi.system.model.constant.RoleConstant;
import com.ssy.lingxi.system.service.LanguageService;
import com.ssy.lingxi.system.utils.UserDetailsUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class LanguageServiceImpl implements LanguageService {
    @Autowired
    LanguageRepository languageRepository;
    @Autowired
    UserDetailsUtil userDetailsUtil;
    @Resource
    SiteRepository siteRepository;
    @Resource
    LanguagePAASControllerFeign languageControllerFeign;

    /**
     * 查询语言设置列表
     * @param request
     * @author wrc
     * @date 2020/5/25
     */
    @Override
    public Wrapper<PageData<LanguageListResponse>> languageList(LanguageListRequest request) {
        PageData pageData = new PageData(0L, null);
        List<LanguageListResponse>  list=new ArrayList<>();
        Language language = new Language();
        language.setName(request.getName());
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name" ,ExampleMatcher.GenericPropertyMatchers.contains());
        Example<Language> example = Example.of(language ,matcher);
        Page<Language> all = languageRepository.findAll(example, PageRequest.of(request.getCurrent(), request.getPageSize(), Sort.by("id").ascending()));
        if (null != all && all.getTotalElements() > 0) {
            all.forEach(languageItem->{
                LanguageListResponse languageListResponse=new LanguageListResponse();
                BeanUtils.copyProperties(languageItem,languageListResponse);
                list.add(languageListResponse);
            });
            pageData = new PageData(all.getTotalElements(),list);
        }
        return Wrapper.success(pageData);
    }

    /**
     * 添加语言
     *
     * @param request
     * @author wrc
     * @date 2020/5/25
     */
    @Transactional
    @Override
    public Wrapper<Void> languageAdd(HttpServletRequest httpServletRequest,Language request) {
        List<Language> allByNameEnEquals = languageRepository.findAllByNameEnEquals(request.getNameEn());
        List<Language> allByNameEquals = languageRepository.findAllByNameEquals(request.getName());
        if(null!=allByNameEnEquals && allByNameEnEquals.size()>0 ){
            return Wrapper.fail("语言英文名字已存在请修改后添加");
        }
        if(null!=allByNameEquals && allByNameEquals.size()>0 ){
            return Wrapper.fail("语言名字已存在请修改后添加");
        }
        MiddlegroundUserLoginResponse loginUserDetails = userDetailsUtil.getLoginUserDetails(httpServletRequest);
        request.setCreateRoleId(loginUserDetails.getId());
        request.setCreateTime(System.currentTimeMillis());
        languageRepository.save(request);

        LanguagePAASDTO synLanguageRequest = new LanguagePAASDTO();
        BeanUtils.copyProperties(request, synLanguageRequest);
        Wrapper wrapper = languageControllerFeign.add(synLanguageRequest);

        return wrapper;
    }

    /***
     * 修改语言设置
     * @param httpServletRequest
     * @param request
     * @return
     */
    @Transactional
    @Override
    public Wrapper<Void> languageUpdate(HttpServletRequest httpServletRequest, Language request) {
        Optional<Language> byId = languageRepository.findById(request.getId());
        if(null==request||!byId.isPresent()){
            return  Wrapper.fail(ResponseCode.DATA_VALID_FAIL,"语言不存在");
        }
        if(null!=request.getState()&& RoleConstant.RoleState.ROLE_STATE_STOP!=request.getState()){
            return Wrapper.fail(ResponseCode.BUSINESS_ERROR,"语言有效状态不能修改");
        }
        List<Language> allByCodeEquals = languageRepository.findAllByNameEnEquals(request.getNameEn());
        List<Language> allByValueEquals = languageRepository.findAllByNameEquals(request.getName());
        if(null!=allByValueEquals&&allByValueEquals.size()>0){
            Map<Long, Language> collect = allByCodeEquals.stream().collect(Collectors.toMap(Language::getId, v -> v));
            collect.remove(request.getId());
            if(null!=collect&&collect.size()>0){
                return Wrapper.fail("语言英文名字已存在请不要重复添加");
            }
        }
        if(null!=allByCodeEquals&&allByCodeEquals.size()>0){
            Map<Long, Language> collect = allByCodeEquals.stream().collect(Collectors.toMap(Language::getId, v -> v));
            collect.remove(request.getId());
            if(null!=collect&&collect.size()>0){
                return Wrapper.fail("语言名字已存在请不要重复添加");
            }
        }
        languageRepository.save(request);

        LanguagePAASDTO synLanguageRequest = new LanguagePAASDTO();
        BeanUtils.copyProperties(request, synLanguageRequest);
        languageControllerFeign.update(synLanguageRequest);

        return Wrapper.success();
    }

    /**
     * 删除语言
     *
     * @param httpServletRequest
     * @param request
     * @author wrc
     * @date 2020/5/25
     */
    @Transactional
    @Override
    public Wrapper<Void> languageDelete(HttpServletRequest httpServletRequest, LanguageDeleteRequest request) {
        Optional<Language> byId = languageRepository.findById(request.getId());
        if(null==request||!byId.isPresent()){
            return Wrapper.fail(ResponseCode.DATA_VALID_FAIL,"语言不存在");
        }
        if(RoleConstant.RoleState.ROLE_STATE_START==byId.get().getState()){
            return Wrapper.fail(ResponseCode.BUSINESS_ERROR,"语言有效状态不能删除");
        }
        languageRepository.deleteById(request.getId());

        LanguagePAASDTO synLanguageRequest = new LanguagePAASDTO();
        BeanUtils.copyProperties(request, synLanguageRequest);
        languageControllerFeign.delete(synLanguageRequest);

        return Wrapper.success();
    }

    /**
     * 查询语言设置详情
     * @param request
     * @author wrc
     * @date 2020/6/3
     */
    @Override
    public Wrapper<LanguageListResponse> languageDetails(com.ssy.lingxi.system.dto.request.LanguageRequest request) {
        Optional<Language> byId = languageRepository.findById(request.getId());
        if(null==request||!byId.isPresent()){
            return  Wrapper.fail(ResponseCode.DATA_VALID_FAIL,"语言不存在");
        }
        LanguageListResponse languageListResponse=new LanguageListResponse();
        Language language = byId.get();
        BeanUtils.copyProperties(language,languageListResponse);
        return Wrapper.success(languageListResponse);
    }

    /**
     * 查询全部语言
     *
     * @author wrc
     * @date 2020/6/3
     */
    @Override
    public Wrapper<List<Language>> languageAll() {
        List<Language> languages = languageRepository.queryByStateEquals(CommonConstant.State.STATE_START);
        return Wrapper.success(languages);
    }

    /**
     * 停用语言
     *
     * @param request
     * @author wrc
     * @date 2020/6/3
     */
    @Transactional
    @Override
    public Wrapper<Void> languageStop(LanguageDeleteRequest request) {
        Language language = languageRepository.findById(request.getId()).orElse(null);
        if(language == null){
            return Wrapper.fail(ResponseCode.DATA_VALID_FAIL,"语言不存在");
        }

        if(CommonConstant.State.STATE_STOP.equals(request.getState())){
            List<Site> sites = siteRepository.findByLanguageId(language.getId());
            if(sites.stream().anyMatch(site -> site.getState().equals(CommonConstant.State.STATE_START))){
                return Wrapper.fail("语言绑定的站点有启用状态，请先禁用相关站点");
            }
        }

        language.setState(request.getState());
        language.setUpdateTime(System.currentTimeMillis());
        languageRepository.saveAndFlush(language);

        LanguagePAASDTO synLanguageRequest = new LanguagePAASDTO();
        BeanUtils.copyProperties(request, synLanguageRequest);
        Wrapper<?> result = languageControllerFeign.state(synLanguageRequest);
        if(result.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        return Wrapper.success();
    }
}
